package com.css.apps.base.common.tree.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.css.apps.base.common.provider.PostQueryProvider;
import com.css.apps.base.common.provider.UserQueryProvider;
import com.css.apps.base.org.model.SOrg;
import com.css.apps.base.post.model.SPost;
import com.css.apps.base.user.model.SUser;
import com.css.core.model.tree.Tree;
import com.css.core.model.tree.TreeCache;
import com.css.core.model.tree.TreeNode;
import com.css.db.query.QueryCache;
import com.css.util.ReflectionUtil;
import com.css.util.StringHelper;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

public class TreeMan {

	/**
	 * 机构树相关
	 */

	private static JSONArray _getOrgTree(String parentId, boolean isAllChild) {
		JSONArray jsonTree = new JSONArray();
		Tree tree = new TreeCache(SOrg.class);
		TreeNode rootNode = tree.getRoot().get(0);
		if (StringHelper.isEmpty(parentId)) {
			parentId = rootNode.getNodeId();
			SOrg parentOrg = QueryCache.get(SOrg.class, parentId);
			JSONObject parentNode = newJsonNode(parentOrg);
			open(parentNode);
			jsonTree.add(parentNode);
		}
		TreeNode tn = tree.getTreeNode(parentId);
		if (tn == null) {
			return jsonTree;
		}
		List<TreeNode> lst = null;
		if (isAllChild)
			lst = tn.getAllChildren();
		else
			lst = tn.getChildren();
		JSONObject one;
		for (TreeNode node : lst) {
			SOrg item = QueryCache.get(SOrg.class, node.getNodeId());
			if (item != null) {
				// 机构节点
				one = newJsonNode(item);
				if (!isAllChild) {
					one.put("isParent", !node.isLeaf());
				}
				jsonTree.add(one);
			}
		}
		return jsonTree;
	}

	public static JSONArray getOrgTree(String parentId, boolean isAllChild) {
		JSONArray tree = _getOrgTree(parentId, isAllChild);
		return tree;
	}

	public static JSONArray getOrgTree(String parentId, String checkIds, boolean isAllChild) {
		JSONArray tree = _getOrgTree(parentId, isAllChild);
		if (StringHelper.isNotEmpty(checkIds)) {
			List<String> checkList = StringHelper.strToList(checkIds);
			for (Object node : tree) {
				JSONObject jsonNode = (JSONObject) node;
				if (checkList.contains(jsonNode.get("id"))) {
					check(jsonNode);
				}
			}
		}
		return tree;
	}

	public static List<String> getOrgChildrenIds(List<String> parentIds, boolean hasOwn) {
		Set<String> childIds = new HashSet<String>();
		if (parentIds != null) {
			Tree tree = new TreeCache(SOrg.class);
			for (String parentId : parentIds) {
				TreeNode rnode = tree.getTreeNode(parentId);
				if (rnode == null)
					continue;
				// 包含自己
				if (hasOwn) {
					childIds.add(parentId);
				}
				List<TreeNode> nodes = rnode.getAllChildren();
				if (nodes != null && nodes.size() > 0) {
					for (TreeNode node : nodes) {
						childIds.add(node.getNodeId());
					}
				}
			}
		}
		List<String> result = new ArrayList<String>();
		result.addAll(childIds);
		return result;
	}

	@SuppressWarnings("unchecked")
	public static List<String> getOrgParentIds(List<String> orgIds, boolean hasOwn) {
		Set<String> parentIds = new HashSet<String>();
		if (orgIds != null) {
			Tree tree = new TreeCache(SOrg.class);
			for (String orgId : orgIds) {
				TreeNode rnode = tree.getTreeNode(orgId);
				if (rnode == null) {
					continue;
				}
				// 包含自己
				if (hasOwn) {
					parentIds.add(orgId);
				}
				List<TreeNode> pnodes = rnode.getParents();
				if (pnodes != null && pnodes.size() > 0) {
					for (TreeNode pnode : pnodes) {
						parentIds.add(pnode.getNodeId());
					}
				}
			}
		}
		List<String> result = new ArrayList<String>();
		result.addAll(parentIds);
		return result;
	}

	/**
	 * 用户树
	 * 
	 * @param orgTree
	 * @return
	 * @throws JSONException
	 */
	public static JSONArray getOrgUserTree(JSONArray orgTree) throws JSONException {
		JSONArray tree = new JSONArray();
		if (orgTree != null) {
			Map<String, List<SUser>> usrMap = UserQueryProvider.getUsers();
			for (int i = 0; i < orgTree.size(); i++) {
				JSONObject orgNode = (JSONObject) orgTree.get(i);
				orgNode.put("isParent", true);
				unUse(orgNode);
				// 机构下的用户
				String orgId = (String) orgNode.get("id");
				List<SUser> usrLst = usrMap.get(orgId);
				if (usrLst != null && usrLst.size() > 0) {
					for (SUser usr : usrLst) {
						JSONObject usrNode = newJsonNode(usr.getUuid(), usr.getRealName(), orgId);
						tree.add(usrNode);
					}
				}
				tree.add(orgNode);
			}
		}
		return tree;
	}

	/**
	 * 用户树
	 */
	public static JSONArray getOrgUserTree(String parentId, boolean isAllChild) {
		JSONArray orgTree = _getOrgTree(parentId, isAllChild);
		JSONArray tree = getOrgUserTree(orgTree);
		return tree;
	}

	public static JSONArray getOrgUserTree(String parentId, String checkIds, boolean isAllChild) {
		JSONArray orgTree = _getOrgTree(parentId, isAllChild);
		JSONArray tree = getOrgUserTree(orgTree);
		if (StringHelper.isNotEmpty(checkIds)) {
			List<String> checkList = StringHelper.strToList(checkIds);
			for (Object node : tree) {
				JSONObject jsonNode = (JSONObject) node;
				if (checkList.contains(jsonNode.get("id"))) {
					check(jsonNode);
				}
			}
		}
		return tree;
	}

	/**
	 * 岗位树
	 */
	public static JSONArray getOrgPostTree(JSONArray orgTree) throws JSONException {
		JSONArray tree = new JSONArray();
		if (orgTree != null) {
			Map<String, List<SPost>> postMap = PostQueryProvider.getPosts();
			for (int i = 0; i < orgTree.size(); i++) {
				JSONObject orgNode = (JSONObject) orgTree.get(i);
				orgNode.put("isParent", true);
				unUse(orgNode);
				// 机构下的岗位
				String orgId = (String) orgNode.get("id");
				List<SPost> postLst = postMap.get(orgId);
				if (postLst != null && postLst.size() > 0) {
					for (SPost post : postLst) {
						JSONObject postNode = newJsonNode(post);
						tree.add(postNode);
					}
				}
				tree.add(orgNode);
			}
		}
		return tree;
	}

	/**
	 * 岗位树
	 */
	public static JSONArray getOrgPostTree(String parentId, boolean isAllChild) {
		JSONArray orgTree = _getOrgTree(parentId, isAllChild);
		JSONArray tree = getOrgPostTree(orgTree);
		return tree;
	}

	/**
	 * 岗位树
	 */
	@SuppressWarnings("unchecked")
	public static JSONArray getPostTree() throws JSONException {
		JSONArray tree = new JSONArray();
		JSONObject one = new JSONObject();
		one.put("id", "0");
		one.put("name", "所有");
		one.put("pId", "-1");
		one.put("isParent", true);
		unUse(one);
		tree.add(one);
		List<String> postIds = new QueryCache("select a.uuid from SPost a").list();
		List<SPost> lst = QueryCache.idToObj(SPost.class, postIds);
		if (lst != null) {
			for (SPost item : lst) {
				one = newJsonNode(item.getUuid(), item.getName(), "0");
				tree.add(one);
			}
		}
		if (tree.size() > 0) {
			open((JSONObject) tree.get(0));
		}
		return tree;
	}

	public static JSONArray getPostTree(String checkIds) {
		JSONArray tree = getPostTree();
		if (StringHelper.isNotEmpty(checkIds)) {
			List<String> checkList = StringHelper.strToList(checkIds);
			for (Object node : tree) {
				JSONObject jsonNode = (JSONObject) node;
				if (checkList.contains(jsonNode.get("id"))) {
					check(jsonNode);
				}
			}
		}
		return tree;
	}

	public static void open(JSONObject one) {
		one.put("open", true);
	}

	public static void check(JSONObject one) {
		one.put("checked", true);
	}

	public static void unCheck(JSONObject one) {
		one.put("use", false);
		one.put("chkDisabled", true);
		one.put("font", "{'cursor':'not-allowed'}");
	}

	public static void unUse(JSONObject one) {
		one.put("use", false);
	}

	private static String getProperty(Object obj, String colName) {
		String dataStr = "";
		try {
			dataStr = ReflectionUtil.invokeMethod(obj, "get" + colName, new Object[] {}).toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataStr;
	}

	/**
	 * uuid name parentId
	 * 
	 * @param obj
	 * @return
	 */
	public static JSONObject newJsonNode(Object obj) {
		JSONObject one = null;
		if (obj != null) {
			one = new JSONObject();
			one.put("id", getProperty(obj, "Uuid"));
			one.put("name", getProperty(obj, "Name"));
			one.put("pId", getProperty(obj, "ParentId"));
		}
		return one;
	}

	public static JSONObject newJsonNode(String id, String name, String pId) {
		JSONObject one = null;
		one = new JSONObject();
		one.put("id", id);
		one.put("name", name);
		one.put("pId", pId);
		return one;
	}

	public static List<TreeNode> getAllChildren(TreeNode tn, List<TreeNode> result) {
		if (result == null)
			result = new ArrayList<TreeNode>();
		if (tn == null)
			return result;
		List<TreeNode> children = tn.getChildren();
		if (children != null) {
			result.addAll(children);
			for (TreeNode node : children) {
				getAllChildren(node, result);
			}
		}
		return result;
	}
}
